<?php
/**
 * +-------------------------------------------------------------
 * |Caption:
 * +-------------------------------------------------------------
 * |Author: Lenny
 * +-------------------------------------------------------------
 * |Email:  1685964109@qq.com
 * +-------------------------------------------------------------
 * |Date:   2024/6/17 下午3:25
 * +-------------------------------------------------------------
 */

namespace app\common\controller;

use app\BaseController;
use app\common\traits\JsonTrait;
use app\common\traits\Curd;
use think\helper\Str;

class AdminController extends BaseController
{
    use JsonTrait;
    use Curd;

    /**
     * 当前应用名称
     * @var string
     */
    protected string $appName;

    /**
     * 是否忽略权限验证
     * @var bool
     */
    protected bool $ignoreAuth = false;

    /**
     * 当前模型
     * @Model
     * @var object
     */
    protected object $model;

    /**
     * 验证类名
     * @var string
     */
    protected string $validateClass;

    /**
     * 字段排序
     * @var array
     */
    protected array $sort = [
            'id' => 'desc',
    ];

    /**
     * 是否关联查询
     * @var bool
     */
    protected bool $relationSearch = false;

    /**
     * 关联查询的表名
     * @var string
     */
    protected string $joinTable;

    /**
     * 关联新增的表名
     * @var string
     */
    protected string $joinAddTable;

    /**
     * 关联更新的表名
     * @var string
     */
    protected string $joinUpdateTable;

    /**
     * 关联删除的表名
     * @var string
     */
    protected string $joinDelTable;

    /**
     * 是否重新组装列表数据
     * @var bool
     */
    protected bool $isListEach = false;

    /**
     * 当前登录的管理员ID
     * @var int|string
     */
    protected int|string $adminUid;

    /**
     * 错误信息
     * @var string
     */
    protected string $msg;

    /**
     * 初始化方法
     * @return void
     */
    public function initialize(): void
    {
        parent::initialize();
        $this->adminUid = request()->adminUserInfo['id'] ?? 0;
        $this->appName  = app()->http->getName();
    }

    /**
     * 通用验证方法
     * @param array $data 待验证的数据
     * @param string $scene 验证场景
     * @param bool $batch 是否批量验证
     */
    protected function sceneValidate(array $data, string $scene, bool $batch = false): bool
    {
        if(empty($this->validateClass)) return true;
        try {
            validate($this->validateClass)->scene($scene)->batch($batch)->check($data);
        } catch (\Exception $e) {
            // 验证失败，返回错误信息
            $this->msg = $e->getMessage();
            return false;
        }
        return true;
    }

    /**
     * 构建请求参数
     * @param array $excludeFields 忽略构建搜索的字段
     * @return array
     */
    protected function buildSearchParams(array $excludeFields = []): array
    {
        $get     = $this->request->get();
        $page    = !empty($get['page']) ? $get['page'] : 1;
        $limit   = !empty($get['limit']) ? $get['limit'] : 15;
        $filters = !empty($get['filter']) ? htmlspecialchars_decode($get['filter']) : '{}';
        $ops     = !empty($get['op']) ? htmlspecialchars_decode($get['op']) : '{}';
        // json转数组
        $filters  = json_decode($filters, true);
        $ops      = json_decode($ops, true);
        $where    = [];
        $excludes = [];
        // 判断是否关联查询
        $tableName = Str::snake(lcfirst($this->model->getName()));
        foreach ($filters as $key => $val) {
            if (in_array($key, $excludeFields)) {
                $excludes[$key] = $val;
                continue;
            }
            $op = !empty($ops[$key]) ? $ops[$key] : '%*%';
            if ($this->relationSearch && count(explode('.', $key)) == 1) {
                $key = "{$tableName}.{$key}";
            }

            switch (strtolower($op)) {
                case '=':
                    $where[] = [$key, '=', $val];
                    break;
                case '%*%':
                    $where[] = [$key, 'LIKE', "%{$val}%"];
                    break;
                case '*%':
                    $where[] = [$key, 'LIKE', "{$val}%"];
                    break;
                case '%*':
                    $where[] = [$key, 'LIKE', "%{$val}"];
                    break;
                case 'range':
                    [$beginTime, $endTime] = explode(' - ', $val);
                    $where[] = [$key, '>=', strtotime($beginTime)];
                    $where[] = [$key, '<=', strtotime($endTime)];
                    break;
                default:
                    $where[] = [$key, $op, "%{$val}"];
            }
        }
        return [$page, $limit, $where, $excludes];
    }

}